/**
* 显示消息提示框
* @param content 提示的标题
*/
export function toast(content) {
  uni.showToast({
    icon: 'none',
    title: content
  })
}

/**
* 显示模态弹窗
* @param content 提示的标题
*/
export function showConfirm(content) {
  return new Promise((resolve, reject) => {
    uni.showModal({
      title: '提示',
      content: content,
      cancelText: '取消',
      confirmText: '确定',
      success: function (res) {
        resolve(res)
      }
    })
  })
}

/**
* 参数处理
* @param params 参数
*/
export function tansParams(params) {
  let result = ''
  for (const propName of Object.keys(params)) {
    const value = params[propName]
    let part = encodeURIComponent(propName) + "="
    if (value !== null && value !== "" && typeof (value) !== "undefined") {
      if (typeof value === 'object') {
        for (const key of Object.keys(value)) {
          if (value[key] !== null && value[key] !== "" && typeof (value[key]) !== 'undefined') {
            let params = propName + '[' + key + ']'
            let subPart = encodeURIComponent(params) + "="
            result += subPart + encodeURIComponent(value[key]) + "&"
          }
        }
      } else {
        result += part + encodeURIComponent(value) + "&"
      }
    }
  }
  return result
}

// 节流
export function throttle(func, time) {
  let start = 0
  return function () {
    const now = new Date()
    if (now - start > time) {
      func.apply(this, arguments)
      start = now
    }
  }
}

// 防抖
export function debounce(func, delay) {
  let timer
  return function () {
    if (timer) clearTimeout(timer)
    let args = arguments
    timer = setTimeout(() => {
      func.apply(this, args)
    }, delay)
  }
}

// 深拷贝
export function deepclone(obj) {
  const objectMap = new Map()
  const extend = (value) => {
    const type = typeof value
    if (type !== 'object' || type === null) {
      return value
    }
    if (objectMap.has(value)) {
      return objectMap.get(value)
    }
    const result = Array.isArray(value) ? [] : {}
    objectMap.set(value, result)
    for (const key in value) {
      result[key] = extend(value[key])
    }
    return result
  }
  return extend(obj)
}

// 分组
export function groupBy(arr, generateKey) {
  if (typeof generateKey === 'string') {
    const propName = generateKey
    generateKey = (item) => item[propName]
  }
  const result = {}
  for (const item of arr) {
    const key = generateKey(item)
    if (!result[key]) {
      result[key] = []
    }
    result[key].push(item)
  }
  return result
}

export const inputPlaceholderStyle = 'color:#999;font-size:32rpx;text-align:left;font-family: PingFang SC, PingFang SC;'

// 输入框提示内容自定义样式
export class CustomPlaceHoder {
  constructor(context = { color: '#999', fontSize: '32rpx', textAlign: 'left', fontFamily: 'PingFang SC, PingFang SC' }) {
    this.color = context.color
    this.fontSize = context.fontSize
    this.textAlign = context.textAlign
    this.fontFamily = context.fontFamily
  }

  get styles() {
    return `color: ${this.color};font-size: ${this.fontSize};text-align: ${this.textAlign};font-family: ${this.fontFamily};`
  }
}

// 加密手机号码
export const getEncryptedPhoneNumber = (tel) => {
  return tel?.replace(/^(\d{3})\d{4}(\d{4})$/, '$1****$2') || tel
}

function _formatterNormalize(formatter) {
  // 参数归一化
  if (typeof formatter === 'function') {
    return formatter
  }
  if (typeof formatter !== 'string') {
    throw new Error('formatter must be a string or a function')
  }
  if (formatter === 'date') {
    formatter = 'yyyy-MM-dd'
  } else if (formatter === 'datetime') {
    formatter = 'yyyy-MM-dd HH:mm:ss'
  }
  return (dateInfo) => {
    const { yyyy, MM, dd, HH, mm, ss } = dateInfo
    return formatter.replace(/yyyy/g, yyyy)
      .replace(/MM/g, MM)
      .replace(/dd/g, dd)
      .replace(/HH/g, HH)
      .replace(/mm/g, mm)
      .replace(/ss/g, ss)
  }
}

/**
* 格式化一个日期
* @param {Date} date 日期参数
*/
export function dateFormate(date, formatter, isPad = true) {
  formatter = _formatterNormalize(formatter)
  function _pad(value, length) {
    if (isPad) {
      return (value + '').padStart(length, '0')
    } else {
      return value.toString()
    }
  }
  const dateInfo = {
    year: date.getFullYear(),
    month: date.getMonth() + 1,
    day: date.getDate(),
    hour: date.getHours(),
    minute: date.getMinutes(),
    second: date.getSeconds(),
    millisecond: date.getMilliseconds()
  }
  dateInfo.yyyy = _pad(dateInfo.year, 4)
  dateInfo.MM = _pad(dateInfo.month, 2)
  dateInfo.dd = _pad(dateInfo.day, 2)
  dateInfo.HH = _pad(dateInfo.hour, 2)
  dateInfo.mm = _pad(dateInfo.minute, 2)
  dateInfo.ss = _pad(dateInfo.second, 2)
  return formatter(dateInfo)
}

// 计算两个日期之间间隔的天数
export const daysDiff = (date1, date2) => Math.ceil(Math.abs(date1 - date2) / 86400000)

/**
* 获取当前时间日期格式
* @param {Date} date 日期参数
*/
export function getNowFormatDate(date) {
  let seperator1 = "-";
  let year = date.getFullYear();
  let month = date.getMonth() + 1;
  let strDate = date.getDate();
  if (month >= 1 && month <= 9) {
	month = "0" + month;
  }
  if (strDate >= 0 && strDate <= 9) {
	strDate = "0" + strDate;
  }
  let currentdate = year + seperator1 + month + seperator1 + strDate;
  return currentdate;
}

// 获取节点信息
export function getDomInfo(identifier, instance) {
  return new Promise((resolve, reject) => {
    const handle = uni.createSelectorQuery().in(instance)
    handle.select(identifier).boundingClientRect(res => {
      if (res) resolve(res)
      else reject()
    }).exec()
  })
}

export const delay = (milliseconds = 1000) => {
	return new Promise((resolve, reject) => {
		setTimeout(resolve, milliseconds)
	})
}

// 对象转url参数
export function buildQueryParams(params) {
  const parts = []
  Object.keys(params).forEach(key => {
    if (params[key] !== undefined && params[key] !== null) {
      const encodedKey = encodeURIComponent(key)
      const encodedValue = encodeURIComponent(params[key])
      parts.push(encodedKey + '=' + encodedValue)
    }
  })
  return parts.join('&')
}

function normalizeChooseAndUploadFileRes(res, fileType) {
	res.tempFiles.forEach((item, index) => {
		if (!item.name) {
			item.name = item.path.substring(item.path.lastIndexOf('/') + 1)
		}
		if (fileType) {
			item.fileType = fileType
		}
		item.cloudPath = Date.now() + '_' + index + item.name.substring(item.name.lastIndexOf('.'))
	})
	if (!res.tempFilePaths) {
		res.tempFilePaths = res.tempFiles.map((file) => file.path)
	}
	return res
}

export function chooseImage(options) {
	const {
		count = 1,
		sizeType = ['original', 'compressed'],
		sourceType = ['album', 'camera'],
		extension
	} = options
	return new Promise((resolve, reject) => {
		uni.chooseImage({
			count,
			sizeType,
			sourceType,
			extension,
			success(res) {
				resolve(normalizeChooseAndUploadFileRes(res, 'image'))
			},
			fail(res) {
				reject(res.errMsg)
			}
		})
	})
}

// 从一个对象中筛选指定的字段
export const picker = (obj, props) => Object.fromEntries(Object.entries(obj).filter(([key]) => props.includes(key)))

// 带缓存的方法
export function memorize(func, resolver) {
  const memorized = function(...args) {
    // 把默认参数中的第一个参数作为键
    const key = resolver ? resolver.apply(this, args) : args[0]
    // 判断缓存中是否存在
    if(memorized.cache.has(key)) {
      // 存在则直接返回缓存中的结果
      return memorized.cache.get(key)
    }
    const result = func.apply(this, args)
    // 把运行后的结果放入缓存
    memorized.cache.set(key, result)
    return result
  }
  memorized.cache = new WeakMap()
  return memorized
}

// 表单字段校验
export const checkFields = (target, rules) => {
  const targetFields = Object.keys(target)
  const ruleList = rules.filter(({ key }) => targetFields.includes(key))
  for (const term of ruleList) {
    if(!target[term.key]) {
      uni.showToast({ title: term.text, icon: 'none' })
      return
    }
    if(term.validateFunc) {
      const { state, value: title } = term.validateFunc(target[term.key])
      if(!state) {
        uni.showToast({ title, icon: 'none' })
        return
      }
    }
  }
  return true
}

// 生成一个指定长度的随机字符串
export const randomString = (len = 6) => {
  return len <= 11 ? Math.random().toString(36).slice(2, 2 + len).padEnd(len, '0') : randomString(11) + randomString(len - 11)
}
